package com.ledim.widget.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Scroller;
import com.ledim.adapter.base.LedimBaseListAdapter;
import com.ledim.utils.LogUtil;

/**
 * Created by ccx on 16/7/26.
 * 首页精选页listview
 */
public class LedimChoiceListView extends ListView {

    private float mLastY = -1; // save event y
    // total list items, used to detect is at the bottom of listview.
    private int mTotalItemCount;
    private Scroller mScroller; // used for scroll back
    //private OnScrollListener mScrollListener; // user's scroll listener

    // the interface to trigger refresh and load more.

    // header view content, use it to calculate the Header's height. And hide it
    // when disable pull refresh.
    private boolean mEnablePullRefresh = true;
    private boolean mPullRefreshing = false; // is refreashing.

    // -- footer view
    private HomeXListViewFooter mFooterView;
    private boolean mEnablePullLoad;
    private boolean mPullLoading;
    private boolean mIsFooterReady = false;

    // for mScroller, scroll back from header or footer.
    private int mScrollBack;
    private final static int SCROLLBACK_HEADER = 0;
    private final static int SCROLLBACK_FOOTER = 1;

    private final static int SCROLL_DURATION = 500; // scroll back duration
    private final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px
    // at bottom, trigger
    // load more.
    private final static float OFFSET_RADIO = 2.0f; // support iOS like pull
    // feature.

    private ChoiceListViewListener listViewListener;

    public void setListViewListener(ChoiceListViewListener listViewListener) {
        this.listViewListener = listViewListener;
    }

    /**
     * @param context
     */
    public LedimChoiceListView(Context context) {
        super(context);
        initWithContext(context);
    }

    public LedimChoiceListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initWithContext(context);
    }

    public LedimChoiceListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initWithContext(context);
    }

    private void initWithContext(Context context) {
        mScroller = new Scroller(context, new DecelerateInterpolator());
        // XListView need the scroll event, and it will dispatch the event to
        // user's listener (as a proxy).
        //super.setOnScrollListener(this);

        // init footer view
        mFooterView = new HomeXListViewFooter(context);
        mFooterView.hide();

        addFooterView(mFooterView);
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(adapter);
        if (adapter instanceof LedimBaseListAdapter) {
            ((LedimBaseListAdapter) adapter).setOnScrollListener(new OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    //if (mScrollListener != null) {
                    //    mScrollListener.onScrollStateChanged(view, scrollState);
                    //}
                    if (mEnablePullLoad && !mPullLoading &&
                            (getLastVisiblePosition() == mTotalItemCount - 1)) {
                        startLoadMore();
                    }

                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                                     int totalItemCount) {
                    // send to user's listener
                    mTotalItemCount = totalItemCount;
                    //if (mScrollListener != null) {
                    //    mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
                    //}
                }
            });
        }
    }

    /**
     * enable or disable pull up load more feature.
     *
     * @param enable
     */
    public void setPullLoadEnable(boolean enable) {
        mEnablePullLoad = enable;
        if (!mEnablePullLoad) {
            // mFooterView.hide();
            mFooterView.show();
            mFooterView.setOnClickListener(null);
            mFooterView.setState(HomeXListViewFooter.STATE_OVER);
            // mFooterView.setEnabled(false);
        } else {
            mPullLoading = false;
            mFooterView.show();
            mFooterView.setState(HomeXListViewFooter.STATE_NORMAL);
            // both "pull up" and "click" will invoke load more.
            mFooterView.setEnabled(true);
            mFooterView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    startLoadMore();
                }
            });
        }
    }

    /**
     * 隐藏加载更多
     */
    public void loadMoreHide() {
        mFooterView.hide();
        mFooterView.setOnClickListener(null);
        mFooterView.setState(HomeXListViewFooter.STATE_OVER);
        mFooterView.setEnabled(false);
    }

    public void startHeaderRefresh() {
        this.mPullRefreshing = true;
    }

    private void updateFooterHeight(float delta) {
        int height = mFooterView.getBottomMargin() + (int) delta;
        if (mEnablePullLoad && !mPullLoading) {
            if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load
                // more.
                mFooterView.setState(HomeXListViewFooter.STATE_READY);
            } else {
                mFooterView.setState(HomeXListViewFooter.STATE_NORMAL);
            }
        } else if (!mEnablePullLoad) {
            if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load
                // more.
                //mFooterView.setState(HomeXListViewFooter.STATE_OVER2);
            } else {
                // mFooterView.setState(HomeXListViewFooter.STATE_OVER1);
            }
        }
        mFooterView.setBottomMargin(height);

        // setSelection(mTotalItemCount - 1); // scroll to bottom
    }

    private void resetFooterHeight() {

        final int bottomMargin = mFooterView.getBottomMargin();
        LogUtil.e("ccx resetFooterHeight===" + bottomMargin);
        final int finalHeight = 0; // default: scroll back to dismiss header.
        // is refreshing, just scroll back to show all the header.

        if (bottomMargin > 0 && mLastY == -1) {
            mScrollBack = SCROLLBACK_FOOTER;

            mScroller.startScroll(0, bottomMargin, 0, finalHeight - bottomMargin, SCROLL_DURATION);
            invalidate();

        }
    }

    public void startLoadMore() {
        mPullLoading = true;
        mFooterView.setState(HomeXListViewFooter.STATE_LOADING);
        if (listViewListener != null) {
            listViewListener.onStartLoadMore();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mLastY == -1) {
            mLastY = ev.getRawY();
        }

        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mLastY = ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                final float deltaY = ev.getRawY() - mLastY;
                mLastY = ev.getRawY();
                if (getLastVisiblePosition() == mTotalItemCount - 1 && (deltaY < 0)) {
                    // last item, already pulled up or want to pull up.
                    updateFooterHeight(-deltaY / OFFSET_RADIO);
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
            default:
                mLastY = -1; // reset
                if (getFirstVisiblePosition() == 0) {
                    // invoke refresh
                    if (mEnablePullRefresh) {
                        mPullRefreshing = true;
                    }
                } else if (getLastVisiblePosition() == mTotalItemCount - 1) {
                    // invoke load more.
                    if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {
                        if (mFooterView.isEnabled()) {
                            startLoadMore();
                        }
                    }
                    resetFooterHeight();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            if (mScrollBack == SCROLLBACK_HEADER) {
            } else {
                LogUtil.e("ccx computeScroll resetFooterHeight===" + mScroller.getCurrY());
                mFooterView.setBottomMargin(mScroller.getCurrY());
            }
            postInvalidate();
        }
        super.computeScroll();
    }


    public interface ChoiceListViewListener {

        void onStartLoadMore();
    }
}

